﻿//==================================================================
// Copyright (C) 2015 福流网络
// 作 者：江怀玉
// 日 期：2015-04-22
// 描 述：规则引擎 用于解析业务逻辑脚本
// 版 本：1.00
// 修改历史纪录
// 版 本  修改时间      修改人            修改内容
//==================================================================

using System;
using System.Activities.Expressions;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using ScriptNET;
using ScriptNET.Runtime;
using ScriptNET.Ast;
using ScriptNET.Processing;
using FL.DBModule;
using FL.Common;
using FL.DAL;


namespace FL.RuleEngine.Core
{
    public class RoleScript : ScriptNET.Script
    {
        public RoleScript()
            : base()
        {

        }

        public RoleScript(IScriptContext contenxt)
            : base(contenxt)
        {
        }
    }

    public class RoleRuntimeHost
    {
        public static void Initialize()
        {
            //加入全局

            //RuntimeHost.
            RuntimeHost.Initialize();
        }
        /// <summary>
        /// 用于数据检查逻辑
        /// </summary>
        /// <param name="entity">对应的实体</param>
        /// <param name="script">业务逻辑脚本</param>
        /// <returns></returns>
        public static string CheckData(BaseEntity entity, string script)
        {
            try
            {
                Initialize();
            }
            catch (Exception e) { };
            RuntimeHost.AddType("baseEntity", typeof(BaseEntity));
            RuntimeHost.AddType("dtBaseEntity", typeof(DataTableBaseEntity));
            RuntimeHost.AddType("dc", typeof(FL.Common.Extend.DataCheck));
            RuntimeHost.AddType("bll", Reflection.CreateInstance("FL.Bussiness.BaseBussnies", "FL.Bussiness").GetType());
            RuntimeHost.AddType("dal", typeof(FL.DAL.DbSql));
            Script _script = RoleScript.Compile(script);
            _script.Context.SetItem("entity", entity);
            object rez = _script.Execute();
            return rez.ToString();
        }

        /// <summary>
        /// 用于 报关单逻辑校验
        /// </summary>
        /// <param name="entity">对应的实体</param>
        /// <param name="script">业务逻辑脚本</param>
        /// <returns></returns>
        //public static string CheckTMainsData(t_mains entity, string script, Dictionary<string, string> dic, List<t_goods_details> goodslist = null, List<t_details> detailslist = null, List<t_accompany_details> accompanylist = null, Dictionary<string, string> tmainextsinfo = null, List<string> goodsControlList = null)
        //{
        //    try
        //    {
        //        Initialize();
        //    }
        //    catch (Exception e) { };

        //    List<int> list = new List<int>();
        //    RuntimeHost.AddType("baseEntity", typeof(BaseEntity));
        //    RuntimeHost.AddType("t_mains", typeof(t_mains));
        //    RuntimeHost.AddType("t_goods_details", typeof(t_goods_details));
        //    RuntimeHost.AddType("t_details", typeof(t_details));
        //    RuntimeHost.AddType("dtBaseEntity", typeof(DataTableBaseEntity));
        //    RuntimeHost.AddType("dc", typeof(FL.Common.Extend.DataCheck));
        //    RuntimeHost.AddType("bll", Reflection.CreateInstance("FL.Bussiness.BaseBussnies", "FL.Bussiness").GetType());
        //    RuntimeHost.AddType("dal", typeof(FL.DAL.DbSql));

        //    RuntimeHost.AddType("string", typeof(string));
        //    RuntimeHost.AddType("double", typeof(double));
        //    RuntimeHost.AddType("ListString", typeof(List<string>));
        //    RuntimeHost.AddType("ListInt", typeof(List<int>));
        //    RuntimeHost.AddType("DataSet", typeof(DataSet));
        //    RuntimeHost.AddType("DataTable", typeof(DataTable));
        //    RuntimeHost.AddType("DataRow", typeof(DataRow));
        //    RuntimeHost.AddType("Queryable", typeof(Queryable));
        //    RuntimeHost.AddType("FL.Entity.DB.Fuliu_TestEntities", typeof(FL.Entity.DB.Fuliu_TestEntities));
        //    RuntimeHost.AddType("Enumerable", typeof(Enumerable));
        //    RuntimeHost.AddType("Regex", typeof(Regex));
        //    RuntimeHost.AddType("DateTime", typeof(DateTime));
        //    RuntimeHost.AddType("Dictionary", typeof(Dictionary<string, string>));

        //    List<int> intlist = new List<int>();
        //    intlist.Add(2);
        //    intlist.Add(4);
        //    intlist.Add(7);
        //    var restul = Enumerable.OfType<int>(intlist);

        //    Script _script = RoleScript.Compile(script);
        //    _script.Context.SetItem("entity", entity);
        //    Fuliu_TestEntities flentity = new Fuliu_TestEntities();

        //    _script.Context.SetItem("tmains", entity);
        //    if (tmainextsinfo != null)
        //        _script.Context.SetItem("tmainextsinfo", tmainextsinfo);

        //    //int goodsnamecount = 0;
        //    //int goodsnocount = 0;
        //    //int country_nocount1 = 0;
        //    int country_nocount2 = 0;
        //    if (goodslist == null)
        //    {
        //        goodslist = new List<t_goods_details>();
        //    }
        //    //else //为同名异归类错误提供数据
        //    //{

        //    //    goodsnamecount = goodslist.GroupBy(g => g.goods_name).Select(g => new { g.Key, count = g.Count() }).Count(g => g.count > 1);
        //    //    goodsnocount = goodslist.GroupBy(g => g.goods_no).Select(g => new { g.Key, count = g.Count() }).Count(g => g.count > 1);
        //    //    if (accompanylist != null)
        //    //    {

        //    //        ////商品编码对应监管条件与报关单不符
        //    //        //var country_nolist = goodslist.Select(s => s.country_no).ToList(); //监管条件
        //    //        //var controllist = accompanylist.Select(s => s.control_no).ToList();//监管代码
        //    //        //country_nocount1 = country_nolist.Where(s => !controllist.Contains(s)).Count();
        //    //        ////输入了无监管条件的证件代码或内容
        //    //        //country_nocount2 = controllist.Where(s => !country_nolist.Contains(s)).Count();

        //    //        List<string> accompanyList = accompanylist.Select(s => s.control_no).ToList();

        //    //        //商品编码对应监管条件与报关单不符
        //    //        country_nocount1 = accompanyList.Where(s => !goodsControlList.Contains(s)).ToList().Count;
        //    //        // country_nocount2 = goodsControlList.Where(s => !accompanyList.Contains(s)).ToList().Count;

        //    //        //输入了无监管条件的证件代码或内容
        //    //        country_nocount2 = 0;
        //    //        if (goodsControlList.Count == 0 & accompanyList.Count > 0)
        //    //        {
        //    //            country_nocount2 = 1;
        //    //        }
        //    //    }

        //    //}
        //    //_script.Context.SetItem("goodsnamecount", goodsnamecount);
        //    //_script.Context.SetItem("goodsnocount", goodsnocount);
        //    //_script.Context.SetItem("country_nocount1", country_nocount1);
        //    //_script.Context.SetItem("country_nocount2", country_nocount2);
        //    _script.Context.SetItem("goodslist", goodslist);

        //    if (detailslist == null)
        //        detailslist = new List<t_details>();
        //    _script.Context.SetItem("detailslist", detailslist);

        //    if (accompanylist == null)
        //        accompanylist = new List<t_accompany_details>();
        //    _script.Context.SetItem("accompanylist", accompanylist);

        //    //通关单 个数
        //    var tgdcount = accompanylist.Count(a => a.control_no.Trim().Equals("B"));
        //    _script.Context.SetItem("tgdcount", tgdcount);

        //    _script.Context.SetItem("flentity", flentity);
        //    _script.Context.SetItem("intlist", intlist);
        //    if (dic != null)
        //    {
        //        foreach (var item in dic)
        //        {
        //            _script.Context.SetItem(item.Key, item.Value);
        //        }
        //    }


        //    // var goods = flentity.t_goods_details.ToList();
        //    intlist.Sum();
        //    object rez = _script.Execute();
        //    return rez.ToString();
        //}

        /// <summary>
        /// 同名异归类错误 只校验 本单是否存在同名异归类
        /// </summary>
        /// <param name="entity"></param>
        public static string CheckGoodsNameType(int id)
        {
            //Fuliu_TestEntities flentity = new Fuliu_TestEntities();
            //List<string> goodsnamelist = flentity.t_goods_details.Where(s => s.t_main_id == id).Select(s => "'" + s.goods_name.Trim() + "'").ToList();
            //if (goodsnamelist.Count<=0)
            //{
            //    return "0";
            //}
            //string goodsnamestr = string.Join(",", goodsnamelist);
            //string sqlstr = string.Format("select distinct goods_no from t_goods_details where t_main_id="+id+" and  goods_name in ({0})", goodsnamestr);
            //FL.DAL.DbSql sqlhelp = new DbSql();
            //DataTable result = sqlhelp.ExecuteQuery(sqlstr);

            string strsql = string.Format(@"
select  goods_no from t_goods_details where t_main_id={0} and  goods_name in ( 
select  goods_name　from t_goods_details　where t_main_id={1}  group by goods_name　having count(*)>1
) group by  goods_no having count(*) =1", id, id);
            FL.DAL.DbSql sqlhelp = new DbSql();
            DataTable result = sqlhelp.ExecuteQuery(strsql);

            if (result.Rows.Count > 0)
            {
                return "1"; //存在同名异归类错误
            }

            return "0";

        }
       
        /// <summary>
        /// 校验是否需要输入通关单号，输入通关单号后是否获取了通关单状态 add by zengtongchun 2015-12-14
        /// </summary>
        /// <param name="id"></param>
        /// <param name="declare_id"></param>
        /// <param name="tgdstatus"></param>
        /// <returns></returns>
//        public static string CheckClearanceState(int id, int declare_id, string tgdstatus)
//        {
//            try
//            {
//                Fuliu_TestEntities flentity = new Fuliu_TestEntities();
//                string code = declare_id == 1 ? "bg_shangpinsuifudanzheng" : "bg_jinkoushangpinsuifudanzheng";
//                List<string> goodsnolist =
//                    flentity.t_goods_details.Where(s => s.t_main_id == id).Select(s => "'" + s.goods_no + "'").ToList();
//                string goodsnostr = string.Join(",", goodsnolist);
//                string controlsql =
//                    string.Format(
//                        "select value+',' from v_data_base_dictionary_detail where code ='{0}' for xml path ('')", code);

//                FL.DAL.DbSql sqlhelp = new DbSql();

//                string goodscontrolsql = string.Format(@"select 
//controls=stuff((select  ','+control from v_t_goods_code  where code_ts in ({0}) for xml path ('')),1,1,'')", goodsnostr);
//                DataTable contorlresult = sqlhelp.ExecuteQuery(controlsql); //进出口 需要监管的条件
//                DataTable goodscontorlresult = sqlhelp.ExecuteQuery(goodscontrolsql); //商品 需要监管的条件
//                var val = goodscontorlresult.Rows[0][0].ToString();
//                if (val.Trim() == "")//无商品监管条件
//                    return "0";
//                var controlstr = contorlresult.Rows[0][0].ToString().Split(',').ToList();
//                var goodscontrolstr =
//                    goodscontorlresult.Rows[0][0].ToString().Trim().ToCharArray().Select(c => c.ToString()).ToList();
//                var result = controlstr.Intersect(goodscontrolstr).ToList(); //交集

//                //随附单据
//                string accompany_detailssql =
//                    string.Format(
//                        " select control_no+'' from t_accompany_details where t_main_id={0} for xml path ('')", id);
//                DataTable accompany_detailsresult = sqlhelp.ExecuteQuery(accompany_detailssql);
//                if (accompany_detailsresult.Rows.Count == 0)
//                    return "1";

//                //商品含B(表示需要通关单)并且 随附单据里含B
//                if (result.Contains("B") && accompany_detailsresult.Rows[0][0].ToString().Contains("B"))
//                {
//                    var accompany = flentity.t_accompany_details.Where(t => t.t_main_id == id).ToList();
//                    int exist = 0;
//                    accompany.ForEach(t =>
//                    {
//                        //存在B但是没有输入通关单号
//                        if (t.control_no == "B" && string.IsNullOrEmpty(t.accompany_no))
//                        {
//                            exist = 1;
//                        }
//                    });
//                    if (exist == 1)
//                    {
//                        return "2"; //根据商品监管条件需要输入通关单号
//                    }
//                    if (string.IsNullOrEmpty(tgdstatus))
//                    {
//                        return "3"; //输入了通关单号还没有获取通关单状态
//                    }
//                    if (!string.IsNullOrEmpty(tgdstatus))
//                    {
//                        return "4";//获取了通关单状态了
//                    }
//                }
//                return "0";
//            }
//            catch (Exception e)
//            {

//                return "4";
//            }

//        }

        /// <summary>
        /// 输入了无监管条件的证件代码或内容
        /// </summary>
        /// <param name="entity"></param>
//        public static string CheckGoodsControl(int id, int declare_id)
//        {
//            try
//            {
//                Fuliu_TestEntities flentity = new Fuliu_TestEntities();
//                string code = declare_id == 1 ? "bg_shangpinsuifudanzheng" : "bg_jinkoushangpinsuifudanzheng";
//                List<string> goodsnolist = flentity.t_goods_details.Where(s => s.t_main_id == id).Select(s => "'" + s.goods_no + "'").ToList();
//                string goodsnostr = string.Join(",", goodsnolist);
//                string controlsql = string.Format("select value+',' from v_data_base_dictionary_detail where code ='{0}' for xml path ('')", code);

//                FL.DAL.DbSql sqlhelp = new DbSql();
//                string goodscontrolsql = string.Format(@"select 
//controls=stuff((select  ','+control from v_t_goods_code  where code_ts in ({0}) for xml path ('')),1,1,'')", goodsnostr);
//                DataTable contorlresult = sqlhelp.ExecuteQuery(controlsql); //进出口 需要监管的条件
//                DataTable goodscontorlresult = sqlhelp.ExecuteQuery(goodscontrolsql); //商品 需要监管的条件
//                var val = goodscontorlresult.Rows[0][0].ToString();
//                if (val.Trim() == "")//无商品监管条件
//                    return "0";
//                var controlstr = contorlresult.Rows[0][0].ToString().Split(',').ToList();
//                var goodscontrolstr = goodscontorlresult.Rows[0][0].ToString().Trim().ToCharArray().Select(c => c.ToString()).ToList();
//                var result = controlstr.Intersect(goodscontrolstr).ToList(); //交集



//                //随附单据
//                string accompany_detailssql = string.Format(" select control_no+'' from t_accompany_details where t_main_id={0} for xml path ('')", id);
//                DataTable accompany_detailsresult = sqlhelp.ExecuteQuery(accompany_detailssql);
//                if (result.Count == 0 && accompany_detailsresult.Rows.Count == 0)
//                    return "0";

//                var accompany_detailstr = accompany_detailsresult.Rows[0][0].ToString().Trim().ToCharArray().Select(c => c.ToString()).ToList();//随附单据

//                var intersect = accompany_detailstr.Intersect(result).ToList();
//                if (intersect.Count != accompany_detailstr.Count)
//                {
//                    return "1";//输入了无监管条件的证件代码或内容
//                }
//                return "0";
//            }
//            catch (Exception e)
//            {
//                return "3";
//            }
//        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="script"></param>
        /// <param name="page"></param>
        /// <returns></returns>
        public static string CheckData(BaseEntity entity, string script, object page)
        {
            if (page == null)
            {
                return CheckData(entity, script);
            }
            try
            {
                Initialize();
            }
            catch (Exception e) { }
            RuntimeHost.AddType("baseEntity", typeof(BaseEntity));
            RuntimeHost.AddType("dc", typeof(FL.Common.Extend.DataCheck));
            RuntimeHost.AddType("bll", Reflection.CreateInstance("FL.Bussiness.BaseBussnies", "FL.Bussiness").GetType());
            RuntimeHost.AddType("dal", typeof(DbSql));
            Script _script = RoleScript.Compile(script);
            _script.Context.SetItem("page", page);
            _script.Context.SetItem("entity", entity);
            object rez = _script.Execute();
            return rez.ToString();
        }

        public static double? CalData(IList<DataTableBaseEntity> list, string script, string Field)
        {
            if (!script.Contains("if"))
            {
                script = "return " + script;
            }
            Script _script = RoleScript.Compile(script);
            foreach (var en in list)
            {
                _script.Context.SetItem(en.TableName, en);
            }

            object rez = _script.Execute();
            return rez as double?;
        }

        /// <summary>
        /// 运行脚本
        /// </summary>
        /// <param name="paras">
        /// 不定参数
        /// length:
        /// =1，参数为纯脚本
        /// =2，实体，脚本 或 业务逻辑，脚本
        /// =3，实体，业务逻辑对象，脚本
        /// =4, 
        /// 超过则抛出异常
        /// </param>
        /// <returns></returns>
        public static object RunCode(params object[] paras)
        {
            //----------------------------
            //定义可变参数
            //----------------------------
            switch (paras.Length)
            {
                case 0:
                    throw new Exception("没有参数，无法进行相关操作");
                case 1:
                    Script _script = RoleScript.Compile(paras[0].ToString());
                    object rez = _script.Execute();
                    return rez;
                case 2:
                    if (paras[0] is BaseEntity)
                    {
                        return CheckData(paras[0] as BaseEntity, paras[1].ToString());
                    }
                    else
                    {
                        return "";
                    }
                default:
                    throw new Exception("未知异常");
            }
            //return "";
        }
    }

}
